#!/usr/bin/env python
# pyglet version of NeHe's OpenGL lesson10
# based on the pygame+PyOpenGL conversion by Paul Furber 2001 - m@verick.co.za
# Philip Bober 2007 pdbober@gmail.com

import os, random
from string import split
from math import sin, cos
from pyglet.gl import *
from pyglet import window
from pyglet import image
from pyglet.window import key
import pyglet.clock


textures = []
filter = 0
tris = []

yrot = 0.0
xpos = 0.0
zpos = 0.0

lookupdown = 0.0
walkbias = 0.0
walkbiasangle = 0.0

LightAmbient  = (GLfloat*4)(0.5, 0.5, 0.5, 1.0)
LightDiffuse  = (GLfloat*4)(1.0, 1.0, 1.0, 1.0)
LightPosition = (GLfloat*4)(0.0, 0.0, 2.0, 1.0)


piover180 = 0.0174532925

def resize(width, height):
	if height==0:
		height=1.0
	glViewport(0, 0, width, height)
	glMatrixMode(GL_PROJECTION)
	glLoadIdentity()
	gluPerspective(45, float(width)/height, 0.1, 100.0)
	glMatrixMode(GL_MODELVIEW)
	glLoadIdentity()

def init():
	global lookupdown, walkbias, walkbiasangle
	
	glEnable(GL_TEXTURE_2D)
	load_textures()
	glShadeModel(GL_SMOOTH)
	glClearColor(0.0, 0.0, 0.0, 0.0)
	glClearDepth(1.0)
	glEnable(GL_DEPTH_TEST)
	glDepthFunc(GL_LEQUAL)
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
	glLightfv( GL_LIGHT1, GL_AMBIENT, LightAmbient )
	glLightfv( GL_LIGHT1, GL_DIFFUSE, LightDiffuse )
	glLightfv( GL_LIGHT1, GL_POSITION, LightPosition )
	glEnable( GL_LIGHT1 )
	lookupdown    = 0.0
	walkbias      = 0.0
	walkbiasangle = 0.0
	glColor4f( 1.0, 1.0, 1.0, 0.5)


def load_textures():
	global textures
	texturefile = os.path.join('data','mud.bmp')
	textureSurface = image.load(texturefile)

	t1=textureSurface.image_data.create_texture(image.Texture)
	glBindTexture(GL_TEXTURE_2D, t1.id)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
	
	t2=textureSurface.image_data.create_texture(image.Texture)
	glBindTexture(GL_TEXTURE_2D, t2.id)
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR )
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR )

	t3=textureSurface.mipmapped_texture
	glBindTexture( GL_TEXTURE_2D, t3.id)
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST )
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR )

	textures=[t1,t2,t3]

def setup_world():
	global tris
	verts = 0
	tri = []
	
	for line in open(os.path.join("data", "world.txt")):
		vals = split(line)
		if len(vals) != 5:
			continue
		if vals[0] == '//':
			continue
		
		vertex = []
		for val in vals:
			vertex.append(float(val))
		tri.append(vertex)
		verts += 1
		if (verts == 3):
			tris.append(tri)
			tri = []
			verts = 0

def draw():
	global xpos, zpos, yrot, walkbias, lookupdown
	global textures, filter, tris

	xtrans = -xpos
	ztrans = -zpos
	ytrans = -walkbias-0.25
	sceneroty=360.0-yrot

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
	glLoadIdentity()
	glRotatef( lookupdown, 1.0, 0.0 , 0.0 )
	glRotatef( sceneroty, 0.0, 1.0 , 0.0 )
	glTranslatef( xtrans, ytrans, ztrans )
	glBindTexture( GL_TEXTURE_2D, textures[filter].id )

	for tri in tris:
		glBegin(GL_TRIANGLES)
		glNormal3f( 0.0, 0.0, 1.0)
		
		glTexCoord2f(tri[0][3], tri[0][4])
		glVertex3f(tri[0][0], tri[0][1], tri[0][2])

		glTexCoord2f(tri[1][3], tri[1][4])
		glVertex3f(tri[1][0], tri[1][1], tri[1][2])

		glTexCoord2f(tri[2][3], tri[2][4])
		glVertex3f(tri[2][0], tri[2][1], tri[2][2])

		glEnd()

def on_key_press(sym, mod):
	global xpos, zpos, yrot, filter
	global piover180, walkbiasangle, walkbias
	
	if sym == key.ESCAPE:
		win.has_exit = True
	elif sym==key.F:
		filter +=1
		if filter == 3:
			filter = 0
	elif sym==key.RIGHT:
		yrot -= 1.5
	elif sym==key.LEFT:
		yrot += 1.5
	elif sym==key.UP:
		xpos -= sin( yrot * piover180 ) * 0.05
		zpos -= cos( yrot * piover180 ) * 0.05
		if ( walkbiasangle >= 359.0 ):
			walkbiasangle = 0.0
		else:
			walkbiasangle += 10.0
		walkbias = sin( walkbiasangle * piover180 ) / 20.0
	elif sym==key.DOWN:
		xpos += sin( yrot * piover180 ) * 0.05
		zpos += cos( yrot * piover180 ) * 0.05
		if ( walkbiasangle <= 1.0 ):
			walkbiasangle = 359.0
		else:
			walkbiasangle -= 10.0
		walkbias = sin( walkbiasangle * piover180 ) / 20.0

def main():
	global win
	win = window.Window(width=640,height=480,visible=False)
	win.on_resize=resize
	win.on_key_press=on_key_press

	init()
	setup_world()

	win.set_visible()
	clock=pyglet.clock.Clock()

	while not win.has_exit:
		win.dispatch_events()
		
		draw()

		win.flip()

		dt=clock.tick()

	print "fps:  %d" % clock.get_fps()

if __name__ == '__main__': main()

